package com.happy3w.ssp.schoolmatehome.service.record;

import com.happy3w.ssp.schoolmatehome.component.html.HtmlHelper;
import com.happy3w.ssp.schoolmatehome.component.image.*;
import com.happy3w.ssp.schoolmatehome.component.image.Canvas;
import com.happy3w.ssp.schoolmatehome.component.image.type.image.ResImage;
import com.happy3w.ssp.schoolmatehome.entity.ClockInRecord;
import com.happy3w.ssp.schoolmatehome.entity.User;
import com.happy3w.ssp.schoolmatehome.exception.MessageException;
import com.happy3w.ssp.schoolmatehome.repository.ClockInRecordRepository;
import com.happy3w.ssp.schoolmatehome.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Slf4j
@RequiredArgsConstructor
@Service
public class ClockInRecordService {
    private final ClockInRecordRepository clockInRecordRepository;
    private final UserRepository userRepository;
    private final TypePrinterManager typePrinterManager;

    public ClockInRecord create(ClockInRecord theRecord, String wxUnionId) {
        Optional<User> userOpt = userRepository.findByWxUnionId(wxUnionId);
        if (userOpt.isPresent()) {
            User user = userOpt.get();
            theRecord.setOwnerId(user.getId());
            theRecord.setCreatedAt(new Date());
            theRecord.setUpdatedAt(new Date());
            return clockInRecordRepository.save(theRecord);
        }
        throw new MessageException("User not found");
    }

    public List<ClockInRecordSummary> findAllByOwner(String wxUnionId) {
        Optional<User> userOpt = userRepository.findByWxUnionId(wxUnionId);
        if (userOpt.isEmpty()) {
            throw new MessageException("User not found");
        }
        User user = userOpt.get();
        return clockInRecordRepository.findByOwnerId(user.getId());
    }

    public Optional<ClockInRecord> findById(Long id, String wxUnionId) {
        Optional<ClockInRecord> recordOpt = clockInRecordRepository.findById(id);
        if (recordOpt.isEmpty()) {
            return Optional.empty();
        }
        Optional<User> userOpt = userRepository.findByWxUnionId(wxUnionId);
        if (userOpt.isEmpty()) {
            return Optional.empty();
        }
        if (recordOpt.get().getOwnerId().equals(userOpt.get().getId())) {
            return recordOpt;
        }
        return Optional.empty();
    }

    public ClockInRecord update(Long id, ClockInRecord theRecord, String wxUnionId) {
        Optional<ClockInRecord> existingRecordOpt = findById(id, wxUnionId);
        if (existingRecordOpt.isPresent()) {
            ClockInRecord existingRecord = existingRecordOpt.get();
            existingRecord.updateBy(theRecord);
            existingRecord.setUpdatedAt(new Date());
            return clockInRecordRepository.save(existingRecord);
        }
        throw new MessageException("Record not found or unauthorized");
    }

    public void delete(Long id, String wxUnionId) {
        Optional<ClockInRecord> recordOpt = findById(id, wxUnionId);
        if (recordOpt.isPresent()) {
            clockInRecordRepository.deleteById(id);
        } else {
            throw new MessageException("Record not found or unauthorized");
        }
    }

    public Optional<byte[]> exportPreview(Long id, int width, String wxUnionId) {
        Optional<ClockInRecord> recordOpt = findById(id, wxUnionId);
        if (recordOpt.isEmpty()) {
            return Optional.empty();
        }
        ClockInRecord theRecord = recordOpt.get();
        DrawPlan drawPlan = buildImagePlan(theRecord, width);
        int border = 10;
        Canvas canvas = new Canvas(drawPlan.getWidth() + border * 2, drawPlan.getHeight() + border * 2,
                border, border);
        drawPlan.draw(canvas);
        return Optional.of(canvas.buildImageBytes());
    }

    private DrawPlan buildImagePlan(ClockInRecord theRecord, int width) {
        try (LinePrintContext context = new LinePrintContext()) {
            context.font(new Font("SimSun", Font.PLAIN, 20))
                    .width(width)
                    .rowHeight(30)
                    .initStartLocation();
            LinePlainBuilder builder = new LinePlainBuilder(context, typePrinterManager)
                    .printLine("时间：", new SimpleDateFormat("yyyy-MM-dd").format(theRecord.getClockInDate()))
                    .printLine("天气：", new ResImage(MessageFormat.format("/template/{0}.png", theRecord.getTheWeather())))
                    .printLine("心情：", new ResImage(MessageFormat.format("/template/{0}.png", theRecord.getTheMood())));
            for (String content : HtmlHelper.html2plainText(theRecord.getContent())) {
                builder.printLine(content);
            }
            return builder.build();
        } catch (Exception e) {
            throw new MessageException("Failed to build plan", e);
        }
    }
}